﻿namespace System;

public static class AssemblyExtension
{
    public static IEnumerable<Type> GetImplementationTypesWithOutAbstractClass<TServiceType>(this Assembly assembly)
        where TServiceType : class
    {
        var implTypes = GetImplementationTypes<TServiceType>(assembly).Where(type => type.IsNotAbstractClass(true));
        return implTypes ?? Array.Empty<Type>();
    }

    public static IEnumerable<Type> GetImplementationTypes<TServiceType>(this Assembly assembly)
    where TServiceType : class
    {
        var serviceType = typeof(TServiceType);
        var implTypes = assembly.ExportedTypes.Where(type => type.IsAssignableTo(serviceType));
        return implTypes ?? Array.Empty<Type>();
    }

    /// <summary>
    /// 根据基类，从指定程序集中获取其实现类
    /// </summary>
    /// <param name="baseType"></param>
    /// <param name="assembly"></param>
    /// <returns></returns>
    public static IEnumerable<Type> GetSubTypeByBaseType(this Assembly assembly, Type baseType)
    {
        var publicTypes = assembly.GetExportedTypes();
        publicTypes = publicTypes.Where(s => s.IsAbstract == false).ToArray();
        foreach (var publicType in publicTypes)
        {
            if (publicType.GetInterfaces().Any(s => s.GUID == baseType.GUID))
                yield return publicType;
            //if (publicType.BaseType?.GUID == baseType.GUID)
            //    yield return publicType;
        }
    }
}